/*!
 * \file Window.h
 * \brief Contains the definition of Window
 * \author CHOUVENC Guillaume, DE CHOULOT Guillaume, MATHIEU Fabien
 */

#ifndef WINDOW_H
#define WINDOW_H

#include <string>
#include <vector>
#include <map>

#include "bga/system/ConfigDLL.h"


namespace sf
{
class Window;
class Event;
}

/**
 * \namespace bga
 * \brief API namespace
 */
namespace bga
{

class WindowListener;
class MouseListener;
class MouseMotionListener;
class KeyListener;

/*!
 * \brief This class represents a window which will contain an OpenGL context
 */
class BOARD_HELL_ENGINE Window
{
	public:
        /*!
         * \brief Contructor
         * \param title : title of the window
         * \param width : width of the window
         * \param height : height of the window
         * \param depth : depth of the window
         *
         * Contructs a new Window which will contain an OpenGL context
         */
		Window(const std::string &title, unsigned int width, unsigned int height, int depth, bool fullscreen);

		/*!
		 * \brief Destructor
		 */
		virtual ~Window();


        /*!
		 *  \brief Test if the window has throw an event
		 *
		 *  Handle all possible events throw by window
		 */
        void handleEvent();

        /*!
		 *  \brief Refresh the content of the window
		 *
		 *  Refresh the content of the window
		 */
        void display();

		/*!
		 * \brief Close the window
		 *
		 * Stop the main loop of the window and close the window
		 */
		void close() const;

		/*!
		 * \brief Test if the window is opened
		 *
		 * Test if the window has been closed
		 */
		bool isOpened() const;

		/*!
		 * \brief Set the cursor position
		 *
		 * Set the cursor position
		 */
		void setCursorPosition(unsigned int x, unsigned int y);

		/*!
		 * \brief Get the center of the window on axis x
		 *
		 * Get the center of the window on axis x
		 */
        unsigned int getCenterX() const;

        /*!
		 * \brief Get the center of the window on axis y
		 *
		 * Get the center of the window on axis y
		 */
        unsigned int getCenterY() const;

		/*!
		 * \brief Get the window's width
		 *
		 * Get the window's width
		 */
		unsigned int getWidth() const;

		/*!
		 * \brief Get the window's height
		 *
		 * Get the window's height
		 */
		unsigned int getHeight() const;

		/**
		 * \brief Get the size of the stencil buffer attached to the current window
		 * \return size in bytes of the stencil buffer
		 */
        unsigned int getSizeStencilBuffer() const;

        /*!
         * \brief add a new window listener to the window
         * \param listener : new window listener to add
         *
         * Add a new listener to handle window events
         */
        void addWindowListener(bga::WindowListener& listener);

        /*!
         * \brief add a new key listener to the window
         * \param listener : new key listener to add
         *
         * Add a new listener to handle key events
         */
        void addKeyListener(bga::KeyListener& listener);

        /*!
         * \brief add a new mouse listener to the window
         * \param listener : new mouse listener to add
         *
         * Add a new listener to handle mouse button events
         */
        void addMouseListener(bga::MouseListener& listener);


	protected:

	private:
        //bool done;  ///<! Value which indicate if the main loop have to stop
        sf::Window *window;   ///!< Private pointer to a SFML window

        /*!
         * \brief Function the handle a Key Event
         * \param Event object having generated the real event
         *
         * This function is called when a key Event has occured. It creates the KeyEvent object and called
         * the matching function of the matching listener
         */
        void handleKeyEvent(const sf::Event& event);

        /*!
         * \brief Function the handle a Window Event
         * \param Event object having generated the real event
         *
         * This function is called when a Window Event has occured. It creates the WindowEvent object and called
         * the matching function of the matching listener
         */
        void handleWindowEvent(const sf::Event& event);

        /*!
         * \brief Function the handle a Mouse Event
         * \param Event object having generated the real event
         *
         * This function is called when a Mouse Event has occured. It creates the MouseEvent object and called
         * the matching function of the matching listener
         */
        void handleMouseEvent(const sf::Event& event);

        /*!
         * \brief Function the handle a Mouse Motion Event
         * \param Event object having generated the real event
         *
         * This function is called when a Mouse Event has occured. It creates the MouseEvent object and called
         * the matching function of the matching listener
         */
        void handleMouseMotionEvent(const sf::Event& event);

        /*!
         * \brief Function the handle a Mouse Wheel Event
         * \param Event object having generated the real event
         *
         * This function is called when a Mouse Wheel Event has occured. It creates the MouseEvent object and called
         * the matching function of the matching listener
         */
        void handleMouseWheelEvent(const sf::Event& event);

        std::vector< bga::WindowListener* > windowListeners;   ///<! Contains all the window listeners
        std::vector< bga::KeyListener* > keyListeners; ///<! Contains all the key listeners
        std::vector< bga::MouseListener* > mouseListeners; ///<! Contains all the mouse listeners


};


}

#endif // WINDOW_H

